/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package nl.hanze.shoestring.dao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;
import nl.hanze.shoestring.dao.ReserveringDAO;
import nl.hanze.shoestring.domain.*;
import nl.hanze.shoestring.logic.Rules;

/**
 *
 * @author alex
 */
public class ReserveringDAOImpl extends BaseDAOImpl<Reservering> implements ReserveringDAO {

    public ReserveringDAOImpl() {
    }

    /**
     * Geeft zoekresultaat terug
     * 
     * @param name Naam van de reis
     * @param startDate Selectie startdatum
     * @param endDate Selectie einddatum
     * @return Lijst met reserveringen
     */     
    @Override
    public List<Reservering> find(String name, Date startDate, Date endDate) {
        boolean hasName = name != null && name.length() > 0;
        boolean hasStartDate = startDate != null;
        boolean hasEndDate = endDate != null;

        if(!hasName && !hasStartDate && !hasEndDate){
            return getAll();
        }
      
        //Lijst met beperkingen
        List<Predicate> prList = new ArrayList<>();
        
        open();

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Reservering> query = cb.createQuery(Reservering.class);
        Root<Reservering> reservering = query.from(Reservering.class);
        Root<Planning> planningRoot = query.from(Planning.class);
        Join<Planning, Reis> planning = reservering.join(Reservering_.planningId).join(Planning_.reisId);
        
        //Genereer beperkingen
        if (hasStartDate && hasEndDate) {
            prList.add(cb.between(reservering.get(Reservering_.datumBoeking), startDate, endDate));
        } else if (hasStartDate) {
            prList.add(cb.greaterThan(reservering.get(Reservering_.datumBoeking), startDate));
        } else if (hasEndDate) {
            prList.add(cb.lessThan(reservering.get(Reservering_.datumBoeking), endDate));
        }

        if (hasName) {
            if(Rules.isNumeric(name)){
                prList.add(cb.equal(reservering.get(Reservering_.id), name));
            }else{
                 prList.add(cb.like(planning.get(Reis_.naam), name + "%"));
            }
            
        }

        //Zet beperkingen om naar lijst
        Predicate[] p = new Predicate[prList.size()];
        prList.toArray(p);
        //Voeg beperkingen toe aan query
        query.where(p);    
            
        TypedQuery<Reservering> typedQuery = em.createQuery(query);
        return typedQuery.getResultList();
    }
}
